package controller;

import entity.FileSystem;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Controller
public class FileAction {

    @Autowired
    private Redisson redisson;

    private final String UPLOAD_LOCK_STR = "upload_lock_redis";

    /**
     *
     * @param request 多部件表单的请求对象
     * @return 上传文件对象的json对象
     * 上传文件的流程：
     * 1. 先把文件保存到web服务器
     * 2. 再从web服务器上把文件上传到FastDFS上
     */
    @RequestMapping("upload")
    @ResponseBody
    public List<FileSystem> upload(MultipartHttpServletRequest request){
        List<FileSystem> list = new ArrayList<>();

        //使用分布式锁
        try {
            //从页面请求中获取上传的文件对象
            List<MultipartFile> files = request.getFiles("file");
            for(MultipartFile file : files){
                RLock rLock = redisson.getLock(UPLOAD_LOCK_STR);
                rLock.lock(30, TimeUnit.SECONDS);
                list.add(uploadFile(file));
                System.out.println("文件上传成功！");
                rLock.unlock();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    @Bean
    public Redisson redisson(){
        Config config = new Config();
        config.useSingleServer().setAddress("redis://192.168.117.133:6379").setDatabase(0);
        return (Redisson)Redisson.create(config);
    }

    private FileSystem uploadFile(MultipartFile file) throws IOException, MyException, InterruptedException {
        /* 1. 把文件上传到web服务器 */
        // 从文件对象中获取文件的原始名称
        String originalFilename = file.getOriginalFilename();
        // 获取后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        // 利用UUID生成不重复文件名
        String filename = UUID.randomUUID().toString() + "." + suffix;
        //创建web服务器保存文件的目录
        File myFile = new File("D:/upload/" + filename);
        //将路径转化成文件
        file.transferTo(myFile);
        //获取服务器的绝对路径
        String absolutePath = myFile.getAbsolutePath();

        Thread.sleep(1000);

        /* 2. 从web服务器上把文件上传到FastDFS上 */
        ClientGlobal.initByProperties("config/fastdfs-client.properties");
        TrackerClient trackerClient = new TrackerClient();
        TrackerServer trackerServer = trackerClient.getConnection();
        StorageServer storageServer = null;
        StorageClient1 storageClient1 = new StorageClient1(trackerServer, storageServer);
        NameValuePair[] list = new NameValuePair[1];
        list[0] = new NameValuePair("fileName", originalFilename);
        String fileId = storageClient1.upload_file1(absolutePath, suffix, list);
        FileSystem fileSystem = new FileSystem(fileId, absolutePath, fileId);
        System.out.println(fileSystem);
        return fileSystem;
    }
}
